home *** CD-ROM | disk | FTP | other *** search
/ PC-Blue - MS DOS Public Domain Library / PC-Blue MS-DOS Public Domain Library - NYACC.iso / vol030 / runoff.bas < prev    next >
Encoding:
BASIC Source File  |  1987-01-11  |  15.3 KB  |  465 lines

  1. 10 REM  RUNOFF - A simple text formatter      February, 1982
  2. 20 REM
  3. 30 REM  COPYRIGHT 1982 John M. Nevison Associates, Concord, Mass.
  4. 32 REM  
  5. 34 REM  Timothy J. Stein
  6. 36 REM  John M. Nevison Associates
  7. 38 REM  Concord, Mass. 01742
  8. 40 REM  (617) 369 4214
  9. 42 REM
  10. 44 REM  Takes a text file and formats it for output to a line
  11. 46 REM  printer, screen, or another file. All lines starting with
  12. 48 REM  a period are considered formatting commands. The program
  13. 50 REM  recognizes these commands:
  14. 52 REM          .PAGE or .P             Force a new page
  15. 54 REM          .SPACING n or .S n      Set line spacing to n
  16. 56 REM          .LEFTMARGIN n or .LM n  Set left margin to column n
  17. 58 REM          .RIGHTMARGIN n or .RM n Set right margin to column n
  18. 60 REM          .JUSTIFY or .J          Fill lines to fit
  19. 62 REM          .NOJUSTIFY or .NJ       Don't bother
  20. 64 REM          .CENTER or .C           Center all lines
  21. 66 REM          .NOCENTER or .NC        Don't center any more
  22. 68 REM          .INCLUDE file or
  23. 70 REM            .I file               Read text from file specified
  24. 72 REM  
  25. 73 REM  A few notes:
  26. 74 REM  1. The program does not reassemble lines. If a line is longer
  27. 75 REM     than the distance from LM to RM it will be truncated.
  28. 76 REM     It will also not be justified or centered.
  29. 77 REM  2. The INCLUDE command cannot be nested. That is, an INCLUDED
  30. 78 REM     file cannot contain an INCLUDE command.
  31. 79 REM
  32. 80 REM  MAJOR VARIABLES:
  33. 81 REM          L$              The current line
  34. 82 REM          PAGE$           One page of lines
  35. 83 REM          V.xxx           Values used globally
  36. 84 REM          S.xxx           Switches used globally
  37. 85 REM
  38. 87 'PAGE
  39. 90 '------------------------------------------------------------------------
  40. 91 ' MAIN LOOP
  41. 92 '
  42. 93 ' 1. Set up initial values, get command names
  43. 94 ' 2. Get file names
  44. 95 ' 3. IF input file entered THEN
  45. 96 '      UNTIL eof seen on input file
  46. 97 '      1. Get a page of text
  47. 98 '      2. Send it out
  48. 99 ' 4. Close files and exit
  49. 100 '-----------------------------------------------------------------------
  50. 102 '
  51. 105 GOSUB 500                           'Initialize
  52. 110 GOSUB 2000                          'Get file names
  53. 120 IF INFILE$ = "" THEN 200
  54. 130   GOSUB 5000                        'Assemble a page
  55. 140   GOSUB 11000                       'Print it out
  56. 150   IF S.EOF = 0 THEN 130              'Until EOF
  57. 160 CLOSE
  58. 200 '
  59. 210 SYSTEM
  60. 390 'PAGE
  61. 400 '------------------------------------------------------------------------
  62. 500 'SUB: Initialize
  63. 510 '------------------------------------------------------------------------
  64. 515 '
  65. 520 DIM PAGE$(60)               'page of text
  66. 530 S.JUSTIFY = 0               'justify off
  67. 540 S.CENTER = 0                'center off
  68. 550 S.EOF = 0                   'not eof yet
  69. 560 S.PAGE = 0                  'not end of page yet
  70. 565 V.PAGE = 1                  'page number
  71. 567 V.INF = 1                   'current input file number
  72. 570 V.LM = 10                   'left margin value
  73. 580 V.RM = 70                   'right margin value
  74. 585 V.COL = V.RM - V.LM + 1     'current column width
  75. 590 V.SPACING = 1               'single spacing value
  76. 595 V.CC$ = "."                 'command character
  77. 597 V.PAGESIZE = 50             'page length
  78. 600 '
  79. 605 DATA 9 
  80. 606                             'number of commands (DIM if greater than 10)
  81. 610 DATA PAGE, P
  82. 620 DATA SPACING, S
  83. 630 DATA LEFTMARGIN, LM
  84. 640 DATA RIGHTMARGIN, RM
  85. 650 DATA JUSTIFY,J
  86. 660 DATA NOJUSTIFY, NJ
  87. 670 DATA CENTER, C
  88. 680 DATA NOCENTER, NC
  89. 685 DATA INCLUDE, I
  90. 690 '
  91. 700 READ NCMDS
  92. 710 FOR I = 1 TO NCMDS
  93. 720   READ CMD$(I), CMDA$(I)
  94. 730 NEXT I
  95. 740 '
  96. 750 RETURN
  97. 1900 'PAGE
  98. 1910 '-----------------------------------------------------------------------
  99. 1920 ' SUB: Get file names
  100. 1921 '      IN: none
  101. 1922 '     OUT: infile$ - input file name (null if none typed)
  102. 1930 '----------------------------------------------------------------------
  103. 1990 '
  104. 2000 CLS
  105. 2100 LOCATE 10,26
  106. 2110 INPUT "File: "; INFILE$
  107. 2120 IF INFILE$ = "" THEN 2410                'return
  108. 2130 ON ERROR GOTO 2160
  109. 2140 OPEN INFILE$ FOR INPUT AS #1
  110. 2150 GOTO 2220
  111. 2160 LOCATE 11,26
  112. 2170   IF ERR = 53 THEN 2200
  113. 2180      PRINT "File open error ";ERR
  114. 2190      GOTO 2210
  115. 2200   PRINT "No such file"
  116. 2210   RESUME 2100
  117. 2220 '
  118. 2225 V.INF = 1
  119. 2230 LOCATE 11,26
  120. 2240 INPUT "Output device: ";O$
  121. 2250 ON ERROR GOTO 2280
  122. 2260 OPEN O$ FOR OUTPUT AS #2
  123. 2270 GOTO 2310
  124. 2280   LOCATE 12,26
  125. 2290   PRINT "Illegal device, error ";ERR
  126. 2300   RESUME 2230
  127. 2310 '
  128. 2311 IF LEFT$(O$,3) <> "LPT" AND LEFT$(O$,3) <> "lpt" THEN 2318
  129. 2312    A$=CHR$(27)+"D"
  130. 2313    LPRINT A$;
  131. 2314    FOR I = 8 TO 64 STEP 8
  132. 2315      LPRINT CHR$(I);
  133. 2316    NEXT I
  134. 2317    PRINT #2,CHR$(0);
  135. 2318 '
  136. 2319 ON ERROR GOTO 0
  137. 2320 LOCATE 12,26
  138. 2330 PRINT "                              "
  139. 2410 RETURN
  140. 4900 'PAGE
  141. 4910 '-----------------------------------------------------------------------
  142. 5000 'SUB: Assemble a page
  143. 5001 '     IN: v.inf - input file number
  144. 5002 '    OUT: s.eof - if end of input file seen
  145. 5003 '         s.page - if .page command seen
  146. 5004 '         v.inf - changed if .include command seen
  147. 5005 '         linecount - number of lines this page
  148. 5006 '         page() - assembled page
  149. 5007 '-----------------------------------------------------------------------
  150. 5010 '
  151. 5020 LINECOUNT = 0
  152. 5030 GOSUB 5500                         'Get a good line
  153. 5040   IF S.EOF = 1 OR S.PAGE = 1 THEN 5100
  154. 5045     IF S.GOODLINE = 0 THEN 5070
  155. 5050       GOSUB 6000                    'Insert a line in the page
  156. 5060       IF LINECOUNT >= V.PAGESIZE THEN 5100
  157. 5070 GOTO 5030
  158. 5100 '
  159. 5110 RETURN
  160. 5400 'PAGE
  161. 5410 '-----------------------------------------------------------------------
  162. 5500 'SUB: Get a good line
  163. 5501 '     IN: v.inf - input file number
  164. 5502 '    OUT: l$ - line
  165. 5503 '         s.goodline - 0 if no text line, 1 if so
  166. 5504 '         v.inf - may have changed if .include seen
  167. 5505 '         s.eof - may be set if end of file seen
  168. 5507 '   NOTE: also processes commands seen; if .justify or .center are
  169. 5508 '         in effect, l$ is returned as justified or centered.
  170. 5509 '-----------------------------------------------------------------------
  171. 5510 '
  172. 5515 S.GOODLINE = 0
  173. 5520 IF EOF(V.INF) THEN 5585
  174. 5530   LINE INPUT #V.INF,L$
  175. 5540   LLEN = LEN(L$)
  176. 5550   IF LEFT$(L$,1) <> V.CC$ THEN 5560
  177. 5553     GOSUB 6500                     'Do command
  178. 5555     GOTO 5600
  179. 5560   IF S.JUSTIFY = 1 THEN GOSUB 8000 'Justify
  180. 5570   IF S.CENTER = 1 THEN GOSUB 8500  'Center line
  181. 5575   S.GOODLINE = 1
  182. 5580   GOTO 5600
  183. 5585 '
  184. 5587 IF V.INF = 1 THEN 5595
  185. 5589   CLOSE V.INF
  186. 5591   V.INF = 1
  187. 5593   GOTO 5520
  188. 5595 '
  189. 5597 S.EOF = 1
  190. 5600 '
  191. 5610 RETURN
  192. 5900 'PAGE
  193. 5910 '-----------------------------------------------------------------------
  194. 6000 'SUB: Insert a line
  195. 6001 '     IN: l$ - line to be inserted
  196. 6002 '         linecount - current number of lines this page
  197. 6003 '    OUT: page$() - page array
  198. 6004 '         linecount - modified to reflect line plus spacing
  199. 6005 '-----------------------------------------------------------------------
  200. 6010 '
  201. 6020 LINECOUNT = LINECOUNT + 1
  202. 6030 PAGE$(LINECOUNT) = LEFT$((SPACE$(V.LM-1) + L$),V.RM)
  203. 6040 IF V.SPACING <= 1 THEN 6100
  204. 6050   FOR I = 1 TO V.SPACING - 1
  205. 6060     LINECOUNT = LINECOUNT + 1
  206. 6070     PAGE$(LINECOUNT) = " "
  207. 6080   NEXT I
  208. 6100 '
  209. 6110 RETURN
  210. 6400 'PAGE
  211. 6410 '-----------------------------------------------------------------------
  212. 6500 'SUB: Do command
  213. 6501 '     IN: l$ - line with command on it (first char is ".")
  214. 6502 '    OUT: none
  215. 6503 '   NOTE: as side effect, the command is done
  216. 6504 '-----------------------------------------------------------------------
  217. 6510 '
  218. 6520 TPOS = 2
  219. 6530 GOSUB 9000                         'Get token
  220. 6540 IF TOKEN$ = "" THEN 6610
  221. 6550   FOR I = 1 TO NCMDS
  222. 6560     IF CMD$(I) = TOKEN$ THEN 6650
  223. 6570   NEXT I
  224. 6580   FOR I = 1 TO NCMDS
  225. 6590     IF CMDA$(I) = TOKEN$ THEN 6650
  226. 6600   NEXT I
  227. 6610   ERRX$ = "Illegal command <" + TOKEN$ + ">"
  228. 6620   GOSUB 10000                      'Print error
  229. 6630   GOTO 6690
  230. 6650 '
  231. 6660 ON I GOSUB 6700, 6800, 6900, 7000, 7100, 7200, 7300, 7400, 7500
  232. 6670 '
  233. 6690 RETURN
  234. 6695 'PAGE
  235. 6697 '-----------------------------------------------------------------------
  236. 6700 'SUB: page eject
  237. 6701 '-----------------------------------------------------------------------
  238. 6710 '
  239. 6720 S.PAGE = 1
  240. 6730 RETURN
  241. 6740 '
  242. 6790 '-----------------------------------------------------------------------
  243. 6800 'SUB: spacing
  244. 6801 '-----------------------------------------------------------------------
  245. 6810 '
  246. 6820 GOSUB 9300                         'Get value
  247. 6830 IF VALUE = -.001 THEN VALUE = 1
  248. 6840   V.SPACING = VALUE
  249. 6850 RETURN
  250. 6860 '
  251. 6890 '-----------------------------------------------------------------------
  252. 6900 'SUB: left margin
  253. 6901 '-----------------------------------------------------------------------
  254. 6910 '
  255. 6920 GOSUB 9300
  256. 6930 IF VALUE = -.001 THEN VALUE = 1
  257. 6940   IF V.RM > VALUE THEN 6947
  258. 6942      ERROR$ = "Left margin greater than right margin"
  259. 6944      GOSUB 10000
  260. 6946      GOTO 6950
  261. 6947   V.LM = VALUE
  262. 6948   V.COL = V.RM - V.LM + 1
  263. 6950 RETURN
  264. 6960 '
  265. 6990 '-----------------------------------------------------------------------
  266. 7000 'SUB: right margin
  267. 7001 '-----------------------------------------------------------------------
  268. 7010 '
  269. 7020 GOSUB 9300
  270. 7030 IF VALUE = -.001 THEN VALUE = 1
  271. 7040   IF V.LM < VALUE THEN 7047
  272. 7042      ERROR$ = "Left margin greater than right margin"
  273. 7044      GOSUB 10000
  274. 7046      GOTO 7050
  275. 7047   V.RM = VALUE
  276. 7048   V.COL = V.RM - V.LM + 1
  277. 7050 RETURN
  278. 7060 '
  279. 7090 '-----------------------------------------------------------------------
  280. 7100 'SUB: justify
  281. 7101 '-----------------------------------------------------------------------
  282. 7110 '
  283. 7120 S.JUSTIFY = 1
  284. 7130 RETURN
  285. 7140 '
  286. 7190 '-----------------------------------------------------------------------
  287. 7200 'SUB: nojustify
  288. 7201 '-----------------------------------------------------------------------
  289. 7210 '
  290. 7220 S.JUSTIFY = 0
  291. 7230 RETURN
  292. 7240 '
  293. 7290 '-----------------------------------------------------------------------
  294. 7300 'SUB: center
  295. 7301 '-----------------------------------------------------------------------
  296. 7310 '
  297. 7320 S.CENTER = 1
  298. 7330 RETURN
  299. 7340 '
  300. 7390 '-----------------------------------------------------------------------
  301. 7400 'SUB: nocenter
  302. 7401 '-----------------------------------------------------------------------
  303. 7410 '
  304. 7420 S.CENTER = 0
  305. 7430 RETURN
  306. 7440 'PAGE
  307. 7490 '-----------------------------------------------------------------------
  308. 7500 'SUB: include
  309. 7501 '-----------------------------------------------------------------------
  310. 7510 '
  311. 7512 IF V.INF = 1 THEN 7520
  312. 7514   ERRX$ = "Cannot nest .include files"
  313. 7516   GOSUB 10000
  314. 7518   GOTO 7650
  315. 7520 GOSUB 9000                         'Get token
  316. 7530 ON ERROR GOTO 7560
  317. 7540 OPEN TOKEN$ FOR INPUT AS #3
  318. 7550   GOTO 7600
  319. 7560 ON ERROR GOTO 0
  320. 7570 ERRX$ = "Error opening .include file " + TOKEN$
  321. 7580 GOSUB 10000
  322. 7590 GOTO 7650
  323. 7600 '
  324. 7610 V.INF = 3
  325. 7620 '
  326. 7650 RETURN
  327. 7900 'PAGE
  328. 7910 '-----------------------------------------------------------------------
  329. 8000 'SUB: JUSTIFY
  330. 8001 '     IN: l$ - line to justify
  331. 8002 '         v.col - column width
  332. 8003 '    OUT: l$ - line justified
  333. 8004 '-----------------------------------------------------------------------
  334. 8010 '
  335. 8020 SCOUNT = 0
  336. 8030 FOR I = 1 TO LLEN
  337. 8040   IF MID$(L$,I,1) = " " THEN SCOUNT = SCOUNT + 1
  338. 8050 NEXT I
  339. 8060 IF SCOUNT = 0 THEN 8400
  340. 8070   LET SLOP = V.COL - LLEN
  341. 8080   IF SLOP <= 0 THEN 8400
  342. 8090   LET SSIZE = INT(SLOP/SCOUNT)
  343. 8100   LET SREM = SLOP - SSIZE * SCOUNT
  344. 8110   L2$ = L$
  345. 8120   L$ = ""
  346. 8130   FOR I = 1 TO LLEN
  347. 8140     X$ = MID$(L2$,I,1)
  348. 8150     L$ = L$ + X$
  349. 8160     IF X$ = " " THEN 8190
  350. 8180       GOTO 8300
  351. 8190     'else
  352. 8200       FOR J = 1 TO SSIZE
  353. 8210         L$ = L$ + " "
  354. 8230       NEXT J
  355. 8240       IF SREM <= 0 THEN 8300
  356. 8250         L$ = L$ + " "
  357. 8260         SREM = SREM - 1
  358. 8300   NEXT I
  359. 8310   LLEN = LEN(L$)
  360. 8320 '
  361. 8400 RETURN
  362. 8490 'PAGE
  363. 8495 '-----------------------------------------------------------------------
  364. 8500 'SUB: Center 
  365. 8501 '     IN: l$ - line to center
  366. 8502 '         v.col - column width
  367. 8503 '    OUT: l$ - line center
  368. 8504 '-----------------------------------------------------------------------
  369. 8510  '
  370. 8520 SLOP = V.COL - LLEN
  371. 8530 IF SLOP <= 0 THEN 8700
  372. 8540   L$ = SPACE$(SLOP/2) + L$
  373. 8550   LLEN = LEN(L$)
  374. 8560 '
  375. 8700 RETURN
  376. 8900 'PAGE
  377. 8910 '-----------------------------------------------------------------------
  378. 9000 'SUB: Get token
  379. 9001 '     IN: l$ - line in which to look for token
  380. 9002 '         tpos - character to start the search
  381. 9003 '         llen - length of line
  382. 9004 '    OUT: token$ - token found, or null if none
  383. 9005 '         tpos - moved to point to char after token
  384. 9007 '   NOTE: tokens delimited by spaces, leading spaces ignored, all
  385. 9008 '         alpha characters shift to upper case
  386. 9009 '-----------------------------------------------------------------------
  387. 9010 '
  388. 9020 TOKEN$ = ""
  389. 9030 FOR I = TPOS TO LLEN
  390. 9040   X$ = MID$(L$,I,1)
  391. 9050   IF X$ <> " " THEN 9080
  392. 9060 NEXT I
  393. 9070 GOTO 9250
  394. 9080 '
  395. 9090 FPOS = I
  396. 9100   FOR I = FPOS TO LLEN
  397. 9110     X$ = MID$(L$,I,1)
  398. 9120     IF X$ = " " THEN 9140
  399. 9130   NEXT I
  400. 9140 '
  401. 9150 TPOS = I + 1
  402. 9160 TOKEN$ = MID$(L$,FPOS,TPOS-FPOS-1)
  403. 9162 X = LEN(TOKEN$)
  404. 9164 FOR I = 1 TO X
  405. 9165   X$ = MID$(TOKEN$,I,1)
  406. 9166   IF X$ < "a" OR X$ > "z" THEN 9169
  407. 9167     X$ = CHR$(ASC(X$) - 32)
  408. 9168     MID$(TOKEN$,I,1) = X$
  409. 9169 NEXT I
  410. 9170 '
  411. 9250 RETURN
  412. 9290 'PAGE
  413. 9295 '-----------------------------------------------------------------------
  414. 9300 'SUB: get value
  415. 9301 '     IN: l$ - line to find value on
  416. 9302 '         tpos - place to start search
  417. 9303 '    OUT: value - numeric value of next token, or -.001 if none
  418. 9304 '         tpos - updated to point after token
  419. 9305 '-----------------------------------------------------------------------
  420. 9310 '
  421. 9320 GOSUB 9000                         'Get token
  422. 9330 ON ERROR GOTO 9400
  423. 9340   VALUE = VAL(TOKEN$)
  424. 9350   GOTO 9450
  425. 9400 RESUME 9410
  426. 9410 VALUE = -.001
  427. 9420 '
  428. 9450 ON ERROR GOTO 0
  429. 9460 RETURN
  430. 9470 '
  431. 9900 'PAGE
  432. 9910 '-----------------------------------------------------------------------
  433. 10000 'SUB: print errors
  434. 10001 '----------------------------------------------------------------------
  435. 10010 '
  436. 10020 PRINT "ERROR: ";ERRX$;" in this line: "
  437. 10030 PRINT "   ";L$
  438. 10040 RETURN
  439. 11000 'SUB: print a page
  440. 11001 '     IN: page$() - page array
  441. 11002 '         linecount - number of lines assembled for this page
  442. 11003 '         v.page - current page number
  443. 11004 '    OUT: v.page - next page number
  444. 11005 '         s.page - reset to 0
  445. 11006 '----------------------------------------------------------------------
  446. 11010 '
  447. 11020 IF LINECOUNT > V.PAGESIZE THEN LINECOUNT = V.PAGESIZE
  448. 11030 FOR I = 1 TO LINECOUNT
  449. 11040   PRINT #2,PAGE$(I)
  450. 11050 NEXT I
  451. 11060 FOR I = 1 TO V.PAGESIZE - LINECOUNT + 4
  452. 11070   PRINT #2," "
  453. 11080 NEXT I
  454. 11090 PRINT #2,SPACE$((V.RM - 7)/2);"--";V.PAGE;"--"
  455. 11100 V.PAGE = V.PAGE + 1
  456. 11110 PRINT #2,CHR$(12)
  457. 11120 S.PAGE = 0
  458. 11130 RETURN
  459. 11140 END
  460. 11900 'PAGE
  461. 11910 '----------------------------------------------------------------------
  462. PAGE = 0
  463. 11130 RETURN
  464. 11140 END
  465. 11900 'PAGE
  466.